import 'package:dio/dio.dart';

/// 自定义异常
class AppException implements Exception {
  final String? _message;
  final int? _code;
  final int? _errorCode;

  AppException(this._code, this._message, this._errorCode);

  @override
  String toString() {
    return "$_code, $_message, $_errorCode";
  }

  int getCode() {
    return _code ?? -1;
  }

  int getErrorCode() {
    return _errorCode ?? -1;
  }

  String getMessage() {
    return _message ?? "unknown error";
  }

  factory AppException.create(DioException error, DioExceptionType errorType) {
    switch (errorType) {
      case DioExceptionType.cancel:
        {
          return BadRequestException(-100, "request cancellation", -1);
        }
      case DioExceptionType.connectionTimeout:
        {
          return BadRequestException(-101, "connection timed out", -1);
        }
      case DioExceptionType.connectionError:
        {
          return BadRequestException(-102, "connection error", -1);
        }
      case DioExceptionType.sendTimeout:
        {
          return BadRequestException(-103, "request timeout", -1);
        }
      case DioExceptionType.receiveTimeout:
        {
          return BadRequestException(-104, "response timeout", -1);
        }
      case DioExceptionType.badCertificate:
        {
          return BadRequestException(-105, "certificate bad", -1);
        }
      case DioExceptionType.badResponse:
        {
          try {
            int? errCode = error.response!.statusCode;
            return AppException(errCode, error.response?.statusMessage, -1);
          } on Exception catch (_) {
            return AppException(-1, "unknown error", -1);
          }
        }
      default:
        {
          return AppException(-1, "unknown error", -1);
        }
    }
  }
}

/// 请求错误
class BadRequestException extends AppException {
  BadRequestException(
    int super.code,
    String super.message,
    int super.errorCode,
  );
}

/// 未认证异常
class UnauthorisedException extends AppException {
  UnauthorisedException(
    int super.code,
    String super.message,
    int super.errorCode,
  );
}
